GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

slideshow.js ➔ onMessageReceived   F
last analyzed

Complexity

Conditions 116

Size

Total Lines 21
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 116
eloc 11
dl 0
loc 21
rs 0
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like slideshow.js ➔ onMessageReceived often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*! UIkit 2.27.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
2
(function(addon) {
3
4
    var component;
5
6
    if (window.UIkit2) {
7
        component = addon(UIkit2);
8
    }
9
10
    if (typeof define == 'function' && define.amd) {
11
        define('uikit-slideshow', ['uikit'], function() {
12
            return component || addon(UIkit2);
13
        });
14
    }
15
16
})(function(UI) {
17
18
    "use strict";
19
20
    var Animations, playerId = 0;
21
22
    UI.component('slideshow', {
23
24
        defaults: {
25
            animation          : 'fade',
26
            duration           : 500,
27
            height             : 'auto',
28
            start              : 0,
29
            autoplay           : false,
30
            autoplayInterval   : 7000,
31
            videoautoplay      : true,
32
            videomute          : true,
33
            slices             : 15,
34
            pauseOnHover       : true,
35
            kenburns           : false,
36
            kenburnsanimations : [
37
                'uk-animation-middle-left',
38
                'uk-animation-top-right',
39
                'uk-animation-bottom-left',
40
                'uk-animation-top-center',
41
                '', // middle-center
42
                'uk-animation-bottom-right'
43
            ]
44
        },
45
46
        current  : false,
47
        interval : null,
48
        hovering : false,
49
50
        boot: function() {
51
52
            // init code
53
            UI.ready(function(context) {
54
55
                UI.$('[data-uk-slideshow]', context).each(function() {
56
57
                    var slideshow = UI.$(this);
58
59
                    if (!slideshow.data('slideshow')) {
60
                        UI.slideshow(slideshow, UI.Utils.options(slideshow.attr('data-uk-slideshow')));
61
                    }
62
                });
63
            });
64
        },
65
66
        init: function() {
67
68
            var $this = this;
69
70
            this.container     = this.element.hasClass('uk-slideshow') ? this.element : UI.$(this.find('.uk-slideshow:first'));
71
            this.current       = this.options.start;
72
            this.animating     = false;
73
74
            this.fixFullscreen = navigator.userAgent.match(/(iPad|iPhone|iPod)/g) && this.container.hasClass('uk-slideshow-fullscreen'); // viewport unit fix for height:100vh - should be fixed in iOS 8
75
76
            if (this.options.kenburns) {
77
78
                this.kbanimduration = this.options.kenburns === true ? '15s': this.options.kenburns;
79
80
                if (!String(this.kbanimduration).match(/(ms|s)$/)) {
81
                    this.kbanimduration += 'ms';
82
                }
83
84
                if (typeof(this.options.kenburnsanimations) == 'string') {
85
                    this.options.kenburnsanimations = this.options.kenburnsanimations.split(',');
86
                }
87
            }
88
89
            this.update();
90
91
            this.on('click.uk.slideshow', '[data-uk-slideshow-item]', function(e) {
92
93
                e.preventDefault();
94
95
                var slide = UI.$(this).attr('data-uk-slideshow-item');
96
97
                if ($this.current == slide) return;
98
99
                switch(slide) {
100
                    case 'next':
101
                    case 'previous':
102
                        $this[slide=='next' ? 'next':'previous']();
103
                        break;
104
                    default:
105
                        $this.show(parseInt(slide, 10));
106
                }
107
108
                $this.stop();
109
            });
110
111
            UI.$win.on("resize load", UI.Utils.debounce(function() {
112
                $this.resize();
113
114
                if ($this.fixFullscreen) {
115
                    $this.container.css('height', window.innerHeight);
116
                    $this.slides.css('height', window.innerHeight);
117
                }
118
            }, 100));
119
120
            // chrome image load fix
121
            setTimeout(function(){
122
                $this.resize();
123
            }, 80);
124
125
            // Set autoplay
126
            if (this.options.autoplay) {
127
                this.start();
128
            }
129
130
            if (this.options.videoautoplay && this.slides.eq(this.current).data('media')) {
131
                this.playmedia(this.slides.eq(this.current).data('media'));
132
            }
133
134
            if (this.options.kenburns) {
135
                this.applyKenBurns(this.slides.eq(this.current));
136
            }
137
138
            this.container.on({
139
                mouseenter: function() { if ($this.options.pauseOnHover) $this.hovering = true;  },
140
                mouseleave: function() { $this.hovering = false; }
141
            });
142
143
            this.on('swipeRight swipeLeft', function(e) {
144
                $this[e.type=='swipeLeft' ? 'next' : 'previous']();
145
            });
146
147
            this.on('display.uk.check', function(){
148
                if ($this.element.is(':visible')) {
149
150
                    $this.resize();
151
152
                    if ($this.fixFullscreen) {
153
                        $this.container.css('height', window.innerHeight);
154
                        $this.slides.css('height', window.innerHeight);
155
                    }
156
                }
157
            });
158
159
            UI.domObserve(this.element, function(e) {
160
                if ($this.container.children(':not([data-slideshow-slide])').not('.uk-slideshow-ghost').length) {
161
                    $this.update(true);
162
                }
163
            });
164
        },
165
166
        update: function(resize) {
167
168
            var $this = this, canvas, processed = 0;
169
170
            this.slides        = this.container.children();
171
            this.slidesCount   = this.slides.length;
172
173
            if (!this.slides.eq(this.current).length) {
174
                this.current = 0;
175
            }
176
177
            this.slides.each(function(index) {
178
179
                var slide = UI.$(this);
180
181
                if (slide.data('processed')) {
182
                    return;
183
                }
184
185
                var media = slide.children('img,video,iframe').eq(0), type = 'html';
186
187
                slide.data('media', media);
188
                slide.data('sizer', media);
189
190
                if (media.length) {
191
192
                    var placeholder;
193
194
                    type = media[0].nodeName.toLowerCase();
195
196
                    switch(media[0].nodeName) {
197
                        case 'IMG':
198
199
                            var cover = UI.$('<div class="uk-cover-background uk-position-cover"></div>').css({'background-image':'url('+ media.attr('src') + ')'});
200
201
                            if (media.attr('width') && media.attr('height')) {
202
                                placeholder = UI.$('<canvas></canvas>').attr({width:media.attr('width'), height:media.attr('height')});
203
                                media.replaceWith(placeholder);
204
                                media = placeholder;
205
                                placeholder = undefined;
206
                            }
207
208
                            media.css({width: '100%',height: 'auto', opacity:0});
209
                            slide.prepend(cover).data('cover', cover);
210
                            break;
211
212
                        case 'IFRAME':
213
214
                            var src = media[0].src, iframeId = 'sw-'+(++playerId);
215
216
                            media
217
                                .attr('src', '').on('load', function(){
218
219
                                    if (index !== $this.current || (index == $this.current && !$this.options.videoautoplay)) {
220
                                        $this.pausemedia(media);
221
                                    }
222
223
                                    if ($this.options.videomute) {
224
225
                                        $this.mutemedia(media);
226
227
                                        var inv = setInterval((function(ic) {
228
                                            return function() {
229
                                                $this.mutemedia(media);
230
                                                if (++ic >= 4) clearInterval(inv);
231
                                            }
232
                                        })(0), 250);
233
                                    }
234
235
                                })
236
                                .data('slideshow', $this)  // add self-reference for the vimeo-ready listener
237
                                .attr('data-player-id', iframeId)  // add frameId for the vimeo-ready listener
238
                                .attr('src', [src, (src.indexOf('?') > -1 ? '&':'?'), 'enablejsapi=1&api=1&player_id='+iframeId].join(''))
239
                                .addClass('uk-position-absolute');
240
241
                            // disable pointer events
242
                            if(!UI.support.touch) media.css('pointer-events', 'none');
243
244
                            placeholder = true;
245
246
                            if (UI.cover) {
247
                                UI.cover(media);
248
                                media.attr('data-uk-cover', '{}');
249
                            }
250
251
                            break;
252
253
                        case 'VIDEO':
254
                            media.addClass('uk-cover-object uk-position-absolute');
255
                            placeholder = true;
256
257
                            if ($this.options.videomute) $this.mutemedia(media);
258
                    }
259
260
                    if (placeholder) {
261
262
                        canvas  = UI.$('<canvas></canvas>').attr({'width': media[0].width, 'height': media[0].height});
263
                        var img = UI.$('<img style="width:100%;height:auto;">').attr('src', canvas[0].toDataURL());
264
265
                        slide.prepend(img);
266
                        slide.data('sizer', img);
267
                    }
268
269
                } else {
270
                    slide.data('sizer', slide);
271
                }
272
273
                if ($this.hasKenBurns(slide)) {
274
275
                    slide.data('cover').css({
276
                        '-webkit-animation-duration': $this.kbanimduration,
277
                        'animation-duration': $this.kbanimduration
278
                    });
279
                }
280
281
                slide.data('processed', ++processed);
282
                slide.attr('data-slideshow-slide', type);
283
            });
284
285
            if (processed) {
286
287
                this.triggers = this.find('[data-uk-slideshow-item]');
288
289
                // Set start slide
290
                this.slides.attr('aria-hidden', 'true').removeClass('uk-active').eq(this.current).addClass('uk-active').attr('aria-hidden', 'false');
291
                this.triggers.filter('[data-uk-slideshow-item="'+this.current+'"]').addClass('uk-active');
292
            }
293
294
            if (resize && processed) {
295
                this.resize();
296
            }
297
        },
298
299
        resize: function() {
300
301
            if (this.container.hasClass('uk-slideshow-fullscreen')) return;
302
303
            var height = this.options.height;
304
305
            if (this.options.height === 'auto') {
306
307
                height = 0;
308
309
                this.slides.css('height', '').each(function() {
310
                    height = Math.max(height, UI.$(this).height());
311
                });
312
            }
313
314
            this.container.css('height', height);
315
            this.slides.css('height', height);
316
        },
317
318
        show: function(index, direction) {
319
320
            if (this.animating || this.current == index) return;
321
322
            this.animating = true;
323
324
            var $this        = this,
325
                current      = this.slides.eq(this.current),
326
                next         = this.slides.eq(index),
327
                dir          = direction ? direction : this.current < index ? 1 : -1,
328
                currentmedia = current.data('media'),
329
                animation    = Animations[this.options.animation] ? this.options.animation : 'fade',
330
                nextmedia    = next.data('media'),
331
                finalize     = function() {
332
333
                    if (!$this.animating) return;
334
335
                    if (currentmedia && currentmedia.is('video,iframe')) {
336
                        $this.pausemedia(currentmedia);
337
                    }
338
339
                    if (nextmedia && nextmedia.is('video,iframe')) {
340
                        $this.playmedia(nextmedia);
341
                    }
342
343
                    next.addClass('uk-active').attr('aria-hidden', 'false');
344
                    current.removeClass('uk-active').attr('aria-hidden', 'true');
345
346
                    $this.animating = false;
347
                    $this.current   = index;
348
349
                    UI.Utils.checkDisplay(next, '[class*="uk-animation-"]:not(.uk-cover-background.uk-position-cover)');
350
351
                    $this.trigger('show.uk.slideshow', [next, current, $this]);
352
                };
353
354
            $this.applyKenBurns(next);
355
356
            // animation fallback
357
            if (!UI.support.animation) {
358
                animation = 'none';
359
            }
360
361
            current = UI.$(current);
362
            next    = UI.$(next);
363
364
            $this.trigger('beforeshow.uk.slideshow', [next, current, $this]);
365
366
            Animations[animation].apply(this, [current, next, dir]).then(finalize);
367
368
            $this.triggers.removeClass('uk-active');
369
            $this.triggers.filter('[data-uk-slideshow-item="'+index+'"]').addClass('uk-active');
370
        },
371
372
        applyKenBurns: function(slide) {
373
374
            if (!this.hasKenBurns(slide)) {
375
                return;
376
            }
377
378
            var animations = this.options.kenburnsanimations,
379
                index      = this.kbindex || 0;
380
381
382
            slide.data('cover').attr('class', 'uk-cover-background uk-position-cover').width();
383
            slide.data('cover').addClass(['uk-animation-scale', 'uk-animation-reverse', animations[index].trim()].join(' '));
384
385
            this.kbindex = animations[index + 1] ? (index+1):0;
386
        },
387
388
        hasKenBurns: function(slide) {
389
            return (this.options.kenburns && slide.data('cover'));
390
        },
391
392
        next: function() {
393
            this.show(this.slides[this.current + 1] ? (this.current + 1) : 0, 1);
394
        },
395
396
        previous: function() {
397
            this.show(this.slides[this.current - 1] ? (this.current - 1) : (this.slides.length - 1), -1);
398
        },
399
400
        start: function() {
401
402
            this.stop();
403
404
            var $this = this;
405
406
            this.interval = setInterval(function() {
407
                if (!$this.hovering) $this.next();
408
            }, this.options.autoplayInterval);
409
410
        },
411
412
        stop: function() {
413
            if (this.interval) clearInterval(this.interval);
414
        },
415
416
        playmedia: function(media) {
417
418
            if (!(media && media[0])) return;
419
420
            switch(media[0].nodeName) {
421
                case 'VIDEO':
422
423
                    if (!this.options.videomute) {
424
                        media[0].muted = false;
425
                    }
426
427
                    media[0].play();
428
                    break;
429
                case 'IFRAME':
430
431
                    if (!this.options.videomute) {
432
                        media[0].contentWindow.postMessage('{ "event": "command", "func": "unmute", "method":"setVolume", "value":1}', '*');
433
                    }
434
435
                    media[0].contentWindow.postMessage('{ "event": "command", "func": "playVideo", "method":"play"}', '*');
436
                    break;
437
            }
438
        },
439
440
        pausemedia: function(media) {
441
442
            switch(media[0].nodeName) {
443
                case 'VIDEO':
444
                    media[0].pause();
445
                    break;
446
                case 'IFRAME':
447
                    media[0].contentWindow.postMessage('{ "event": "command", "func": "pauseVideo", "method":"pause"}', '*');
448
                    break;
449
            }
450
        },
451
452
        mutemedia: function(media) {
453
454
            switch(media[0].nodeName) {
455
                case 'VIDEO':
456
                    media[0].muted = true;
457
                    break;
458
                case 'IFRAME':
459
                    media[0].contentWindow.postMessage('{ "event": "command", "func": "mute", "method":"setVolume", "value":0}', '*');
460
                    break;
461
            }
462
        }
463
    });
464
465
    Animations = {
466
467
        'none': function() {
468
469
            var d = UI.$.Deferred();
470
            d.resolve();
471
            return d.promise();
472
        },
473
474 View Code Duplication
        'scroll': function(current, next, dir) {
475
476
            var d = UI.$.Deferred();
477
478
            current.css('animation-duration', this.options.duration+'ms');
479
            next.css('animation-duration', this.options.duration+'ms');
480
481
            next.css('opacity', 1).one(UI.support.animation.end, function() {
482
483
                current.css('opacity', 0).removeClass(dir == -1 ? 'uk-slideshow-scroll-backward-out' : 'uk-slideshow-scroll-forward-out');
484
                next.removeClass(dir == -1 ? 'uk-slideshow-scroll-backward-in' : 'uk-slideshow-scroll-forward-in');
485
                d.resolve();
486
487
            }.bind(this));
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
488
489
            current.addClass(dir == -1 ? 'uk-slideshow-scroll-backward-out' : 'uk-slideshow-scroll-forward-out');
490
            next.addClass(dir == -1 ? 'uk-slideshow-scroll-backward-in' : 'uk-slideshow-scroll-forward-in');
491
            next.width(); // force redraw
492
493
            return d.promise();
494
        },
495
496 View Code Duplication
        'swipe': function(current, next, dir) {
497
498
            var d = UI.$.Deferred();
499
500
            current.css('animation-duration', this.options.duration+'ms');
501
            next.css('animation-duration', this.options.duration+'ms');
502
503
            next.css('opacity', 1).one(UI.support.animation.end, function() {
504
505
                current.css('opacity', 0).removeClass(dir === -1 ? 'uk-slideshow-swipe-backward-out' : 'uk-slideshow-swipe-forward-out');
506
                next.removeClass(dir === -1 ? 'uk-slideshow-swipe-backward-in' : 'uk-slideshow-swipe-forward-in');
507
                d.resolve();
508
509
            }.bind(this));
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
510
511
            current.addClass(dir == -1 ? 'uk-slideshow-swipe-backward-out' : 'uk-slideshow-swipe-forward-out');
512
            next.addClass(dir == -1 ? 'uk-slideshow-swipe-backward-in' : 'uk-slideshow-swipe-forward-in');
513
            next.width(); // force redraw
514
515
            return d.promise();
516
        },
517
518
        'scale': function(current, next, dir) {
519
520
            var d = UI.$.Deferred();
521
522
            current.css('animation-duration', this.options.duration+'ms');
523
            next.css('animation-duration', this.options.duration+'ms');
524
525
            next.css('opacity', 1);
526
527
            current.one(UI.support.animation.end, function() {
528
529
                current.css('opacity', 0).removeClass('uk-slideshow-scale-out');
530
                d.resolve();
531
532
            }.bind(this));
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
533
534
            current.addClass('uk-slideshow-scale-out');
535
            current.width(); // force redraw
536
537
            return d.promise();
538
        },
539
540
        'fade': function(current, next, dir) {
541
542
            var d = UI.$.Deferred();
543
544
            current.css('animation-duration', this.options.duration+'ms');
545
            next.css('animation-duration', this.options.duration+'ms');
546
547
            next.css('opacity', 1);
548
549
            // for plain text content slides - looks smoother
550
            if (!(next.data('cover') || next.data('placeholder'))) {
551
552
                next.css('opacity', 1).one(UI.support.animation.end, function() {
553
                    next.removeClass('uk-slideshow-fade-in');
554
                }).addClass('uk-slideshow-fade-in');
555
            }
556
557
            current.one(UI.support.animation.end, function() {
558
559
                current.css('opacity', 0).removeClass('uk-slideshow-fade-out');
560
                d.resolve();
561
562
            }.bind(this));
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
563
564
            current.addClass('uk-slideshow-fade-out');
565
            current.width(); // force redraw
566
567
            return d.promise();
568
        }
569
    };
570
571
    UI.slideshow.animations = Animations;
572
573
    // Listen for messages from the vimeo player
574
    window.addEventListener('message', function onMessageReceived(e) {
575
576
        var data = e.data, iframe;
577
578
        if (typeof(data) == 'string') {
579
580
            try {
581
                data = JSON.parse(data);
582
            } catch(err) {
583
                data = {};
584
            }
585
        }
586
587
        if (e.origin && e.origin.indexOf('vimeo') > -1 && data.event == 'ready' && data.player_id) {
588
            iframe = UI.$('[data-player-id="'+ data.player_id+'"]');
589
590
            if (iframe.length) {
591
                iframe.data('slideshow').mutemedia(iframe);
592
            }
593
        }
594
    }, false);
595
596
});
597